/**
  ******************************************************************************
  * @file    can.c
  * @brief   This file provides code for the configuration
  *          of the CAN instances.
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "can.h"

/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

CAN_HandleTypeDef hcan;

/* CAN init function */
void MX_CAN_Init(void)
{

  /* USER CODE BEGIN CAN_Init 0 */

  /* USER CODE END CAN_Init 0 */

  /* USER CODE BEGIN CAN_Init 1 */

  /* USER CODE END CAN_Init 1 */
  hcan.Instance = CAN1;
  hcan.Init.Prescaler = 3;
  hcan.Init.Mode = CAN_MODE_NORMAL;
  hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;
  hcan.Init.TimeSeg1 = CAN_BS1_7TQ;
  hcan.Init.TimeSeg2 = CAN_BS2_4TQ;
  hcan.Init.TimeTriggeredMode = DISABLE;
  hcan.Init.AutoBusOff = DISABLE;
  hcan.Init.AutoWakeUp = DISABLE;
  hcan.Init.AutoRetransmission = DISABLE;
  hcan.Init.ReceiveFifoLocked = DISABLE;
  hcan.Init.TransmitFifoPriority = DISABLE;
  if (HAL_CAN_Init(&hcan) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN CAN_Init 2 */

  /* USER CODE END CAN_Init 2 */

}

void HAL_CAN_MspInit(CAN_HandleTypeDef* canHandle)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(canHandle->Instance==CAN1)
  {
  /* USER CODE BEGIN CAN1_MspInit 0 */

  /* USER CODE END CAN1_MspInit 0 */
    /* CAN1 clock enable */
    __HAL_RCC_CAN1_CLK_ENABLE();

    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**CAN GPIO Configuration
    PA11     ------> CAN_RX
    PA12     ------> CAN_TX
    */
    GPIO_InitStruct.Pin = GPIO_PIN_11;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_12;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /* CAN1 interrupt Init */
    HAL_NVIC_SetPriority(USB_LP_CAN1_RX0_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn);
    HAL_NVIC_SetPriority(CAN1_RX1_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(CAN1_RX1_IRQn);
  /* USER CODE BEGIN CAN1_MspInit 1 */

  /* USER CODE END CAN1_MspInit 1 */
  }
}

void HAL_CAN_MspDeInit(CAN_HandleTypeDef* canHandle)
{

  if(canHandle->Instance==CAN1)
  {
  /* USER CODE BEGIN CAN1_MspDeInit 0 */

  /* USER CODE END CAN1_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_CAN1_CLK_DISABLE();

    /**CAN GPIO Configuration
    PA11     ------> CAN_RX
    PA12     ------> CAN_TX
    */
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11|GPIO_PIN_12);

    /* CAN1 interrupt Deinit */
    HAL_NVIC_DisableIRQ(USB_LP_CAN1_RX0_IRQn);
    HAL_NVIC_DisableIRQ(CAN1_RX1_IRQn);
  /* USER CODE BEGIN CAN1_MspDeInit 1 */

  /* USER CODE END CAN1_MspDeInit 1 */
  }
}

/* USER CODE BEGIN 1 */

//这里要自己配过滤�?(直接把F4的程序COPY过来)
void CAN1_Filter_Init(void)
{
	CAN_FilterTypeDef CAN1_FilterConf;
	CAN1_FilterConf.FilterIdHigh=0X0000;
	CAN1_FilterConf.FilterIdLow=0X0000;  //set id for filter
	CAN1_FilterConf.FilterMaskIdHigh=0X0000;
	CAN1_FilterConf.FilterMaskIdLow=0X0000;  //set mask_id for filter
	CAN1_FilterConf.FilterFIFOAssignment=CAN_FILTER_FIFO0;  //设置FIFO与过滤器的关联关�?
	CAN1_FilterConf.FilterActivation=ENABLE;  //�?活过滤器
	CAN1_FilterConf.FilterMode=CAN_FILTERMODE_IDMASK;  //设置模式
	CAN1_FilterConf.FilterScale=CAN_FILTERSCALE_32BIT;  //设置过滤器的位宽�?2*16 or 1*32�?
	CAN1_FilterConf.FilterBank=0;  //设置初始化的过滤器组

	if(HAL_CAN_ConfigFilter(&hcan, &CAN1_FilterConf)!=HAL_OK)
	{
		printf("CAN Filter Config Fail!\r\n");
		Error_Handler();
	}

	printf("CAN Filter Config Success!\r\n");
}

//发�?�标准ID的数据帧
uint8_t CANx_SendStdData(CAN_HandleTypeDef* hcan,uint16_t ID,uint8_t *pData,uint16_t Len)
{
  static CAN_TxHeaderTypeDef   Tx_Header;

	Tx_Header.StdId=ID;
	Tx_Header.ExtId=0;
	Tx_Header.IDE=CAN_ID_STD;
	Tx_Header.RTR=0;
	Tx_Header.DLC=Len;
        /*找到空的发�?�邮箱，把数据发送出�?*/
	if (HAL_CAN_AddTxMessage(&hcan, &Tx_Header, pData, (uint32_t*)CAN_TX_MAILBOX0) != HAL_OK) {
        printf("CAN send test data fail!\r\n");
        Error_Handler();
    }

	printf("CAN send data success!\r\n");
}

//发�?�扩展ID的数据帧
uint8_t CANx_SendExtData(CAN_HandleTypeDef* hcan,uint32_t ID,uint8_t *pData,uint16_t Len)
{
	static CAN_TxHeaderTypeDef   Tx_Header;

	Tx_Header.RTR=0;
	Tx_Header.DLC=Len;
	Tx_Header.StdId=0;
	Tx_Header.ExtId=ID;
	Tx_Header.IDE=CAN_ID_EXT;
       /*找到空的发�?�邮箱，把数据发送出�?*/
	if (HAL_CAN_AddTxMessage(&hcan, &Tx_Header, pData, (uint32_t*)CAN_TX_MAILBOX0) != HAL_OK) {
        printf("CAN send test data fail!\r\n");
        Error_Handler();
    }

	//printf("CAN send data success!\r\n");
	printf("CAN send data success!\r\n");
}

/** 数据的接�?
 * @brief  CAN FIFO0的中断回调函数，在里面完成数据的接收
 * @param  hcan     CAN的句�?
 */

uint8_t date_CAN1[8];//设为全局变量，用于接收CAN1数据
uint8_t date_CAN2[8];//设为全局变量，用于接收CAN2数据

//CAN接收中断处理函数
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
	if(hcan->Instance ==CAN1)
	{
	  CAN_RxHeaderTypeDef RxHeader;  //接受句柄
	  HAL_CAN_GetRxMessage(&hcan, CAN_RX_FIFO0, &RxHeader, date_CAN1); //接收，CAN邮箱�?0
	  //    各参数的含义�?    can1  FIFO0(接收邮箱0�?  接收容器   用于接收数据

	  printf("--->Data Receieve!\r\n");
	  printf("RxMessage.StdId is %#x\r\n",  RxHeader.StdId);
	  printf("data[0] is 0x%02x\r\n", date_CAN1[0]);
	  printf("data[1] is 0x%02x\r\n", date_CAN1[1]);
	  printf("data[2] is 0x%02x\r\n", date_CAN1[2]);
	  printf("data[3] is 0x%02x\r\n", date_CAN1[3]);
	  printf("data[4] is 0x%02x\r\n", date_CAN1[4]);
	  printf("data[5] is 0x%02x\r\n", date_CAN1[5]);
	  printf("data[6] is 0x%02x\r\n", date_CAN1[6]);
	  printf("data[7] is 0x%02x\r\n", date_CAN1[7]);
	  printf("<---\r\n");

	  return ;
	}
	else
		printf("Receive failed...\r\n");

	HAL_CAN_ActivateNotification(hcan, CAN_IT_RX_FIFO0_MSG_PENDING);// 再次使能FIFO0接收中断
}
/* USER CODE END 1 */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
